package com.miku.sys.config;

import java.io.File;
import java.io.IOException;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.google.common.collect.Maps;
import com.miku.common.PageControl;
import com.miku.sys.utils.UserUtils;
import com.miku.utils.OSUtils;
import com.miku.utils.PropertiesLoader;
import com.miku.utils.StringUtils;

/**
 * 全局配置类
 */
public class Global {
	
	enum Mode{
		Develop,					//开发者模式
		Release					//发布模式，即在服务器上的模式
	}

	//当前运行实例的模式，如果在开发模式下，有些方式会不同
	//例如微信的accessToken的获取和刷新，必须在Release模式下才会执行
	//Develop模式则会去服务器获取
	private static Mode mode = null;
	
	/**
	 * 当前对象实例
	 */
	private static Global global = new Global();
	
	private static Logger logger = Logger.getLogger(Global.class.getName());
	
	/**
	 * 保存全局属性值
	 */
	private static Map<String, String> map = Maps.newHashMap();
	
	/**
	 * 属性文件加载对象
	 */
	private static PropertiesLoader loader = new PropertiesLoader("miku.properties");

	/**
	 * 显示/隐藏
	 */
	public static final String SHOW = "1";
	public static final String HIDE = "0";

	/**
	 * 是/否
	 */
	public static final String YES = "yes";
	public static final String NO = "no";
	
	/**
	 * 对/错
	 */
	public static final String TRUE = "true";
	public static final String FALSE = "false";
	
	/**
	 * 上传文件基础虚拟路径
	 */
	public static final String USERFILES_BASE_URL = "/userfiles/";
	
	//微信accesstoken刷新时间为600秒
	public static final int wxAccessTokenRefreshTime = 7000;
	
	//微信jsticket的刷新时间为7000秒
	public static final int wxJSTicketRefreshTime = 7000;
	
	//由实例启动的时候调用
	public static void initialize(){
		if(new File(getConfig("debug.servermode.auto.detect.from.appoint.file")).exists()){
			//如果这个文件或者目录存在，就表示是release模式，因为目前来讲只有服务器有这个位置有文件的
			mode = Mode.Release;
		}else{
			mode = Mode.Develop;
		}
	}
	
	public static boolean isDevepMode(){
		if(mode == null) throw new RuntimeException("模式为空");
		return mode == Mode.Develop;
	}
	
	//是否为发布模式
	public static boolean isReleaseMode(){
		if(mode == null) throw new RuntimeException("模式为空");
		return mode == Mode.Release;
	}
	
	public static String getModeString(){
		if(mode == Mode.Develop){
			return "开发模式";
		}else if(mode == Mode.Release){
			return "发布模式";
		}
		return "未定义模式";
	}
	
	/**
	 * 获取当前对象实例
	 */
	public static Global getInstance() {
		return global;
	}
	
	public static String getDataDir(){
		return getConfigDifferenceOS("data.dir.path");
	}
	
	/**
	 * 获取系统图片路径，返回c:/image
	 * @return
	 */
	public static String getImageDir(){
		return getDataDir() + "/image";
	}
	
	/**
	 * 获取配置
	 * @see ${fns:getConfig('adminPath')}
	 */
	public static String getConfig(String key) {
		String value = map.get(key);
		if (value == null){
			value = loader.getProperty(key);
			map.put(key, value != null ? value : org.apache.commons.lang3.StringUtils.EMPTY);
		}
		return value;
	}
	
	/**
	 * 获取页面翻页器
	 * @return
	 */
	public static PageControl getSearchEnginePageControl(){
		return (PageControl) UserUtils.getSession().getAttribute(SessionKeyDefine.pageSearchEngineControl);
	}
	
	/**
	 * 获取配置，区分os对待，比如linux下得到的是key+".linux"的配置，而windows下则是key + ".windows"
	 * @param key
	 * @return 
	 */
	public static String getConfigDifferenceOS(String key){
			return getConfig(key + "." + OSUtils.osName());
	}

	/**
	 * 网页web的根路径/web
	 */
	public static String getWebRoot() {
		return getConfig("web.url.root");
	}
	
	/**
	 * 获取开发者和服务器通信的签名，密匙
	 */
	public static String getDevepSign(){
		return getConfig("debug.system.signature");
	}
	
	/**
	 * 网页web的根路径/web
	 */
	public static String getManagerRoot() {
		return getConfig("manager.url.root");
	}
	
	/**
	 * 网页web的主页路径/search，一般得拼接下，root加上home就是 /web/search
	 */
	public static String getWebHome() {
		return getConfig("web.url.home");
	}
	
	/**
	 * 微信的根路径/wechat
	 */
	public static String getWechatRoot() {
		return getConfig("wechat.url.root");
	}
	
	/**
	 * 微信的主页路径/search，一般得拼接下，root加上home就是 /wechat/search
	 */
	public static String getWechatHome() {
		return getConfig("wechat.url.home");
	}
	
	/**
	 * 获取网站主题
	 * @return
	 */
	public static String getTheme(){
		return getConfig("theme");
	}
	
	/**
	 * 获取URL后缀
	 */
	public static String getUrlSuffix() {
		return getConfig("urlSuffix");
	}
	
	/**
	 * 页面获取常量
	 * @see ${fns:getConst('YES')}
	 */
	public static Object getConst(String field) {
		try {
			return Global.class.getField(field).get(null);
		} catch (Exception e) {
			// 异常代表无配置，这里什么也不做
		}
		return null;
	}

	/**
	 * 获取上传文件的根目录
	 * @return
	 */
	public static String getUserfilesBaseDir() {
		logger.error("获取上传文件根目录，被修改了，没东西了");
		return null;
		/*String dir = getConfig("userfiles.basedir");
		if (StringUtils.isBlank(dir)){
			try {
				dir = ServletContextFactory.getServletContext().getRealPath("/");
			} catch (Exception e) {
				return "";
			}
		}
		if(!dir.endsWith("/")) {
			dir += "/";
		}
		return dir;*/
	}
	
    /**
     * 获取工程路径
     * @return
     */
    public static String getProjectPath(){
    	// 如果配置了工程路径，则直接返回，否则自动获取。
		String projectPath = Global.getConfig("projectPath");
		if (org.apache.commons.lang3.StringUtils.isNotBlank(projectPath)){
			return projectPath;
		}
		try {
			File file = new DefaultResourceLoader().getResource("").getFile();
			if (file != null){
				while(true){
					File f = new File(file.getPath() + File.separator + "src" + File.separator + "main");
					if (f == null || f.exists()){
						break;
					}
					if (file.getParentFile() != null){
						file = file.getParentFile();
					}else{
						break;
					}
				}
				projectPath = file.toString();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return projectPath;
    }
	
    public static void setRequestAttrib(String name, Object o){
    	((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest().setAttribute(name, o);
    }
    
    /**
     * 四舍五入数值，保留指定位数小数，返回字符串
     * @param n    指定数值
     * @param fix  保留的小数位数
     * @return  四舍五入后的字符串
     */
    public static String roundNumber(double n, int fix){
    	return String.format("%." + fix + "f", n);
    }
}